use crate::config::Config;
use crate::db::Database;
use crate::handlers;
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
use std::convert::Infallible;
use std::sync::Arc;
use tokio::sync::Mutex;
use crate::handlers::DeviceParams;
use hyper::http::response::Builder;

fn set_response_headers(builder: Builder) -> Builder {
    builder.header("Content-Type", "text/plain; charset=utf-8")
}

// 在 server.rs 文件中更新请求处理函数
async fn handle_request(req: Request<Body>, db: Arc<Mutex<Database>>) -> Result<Response<Body>, Infallible> {
    match req.uri().path() {
        "/join" => {
            let body_bytes = hyper::body::to_bytes(req.into_body()).await.unwrap();
            println!("原始包（原始十六进制形式）：{:?} 的长度为 {:?}", &body_bytes, &body_bytes.len());

            let data = body_bytes.as_ref();
            println!("原始包data（二进制形式）：{:?} 的长度为 {:?}", &data, &data.len());

            match handlers::join::handle_join_request(data, &db).await {
                Ok(join_accept_msg) => {
                    let response = Response::new(Body::from(join_accept_msg));
                    Ok(set_response_headers(Response::builder()).body(response.into_body()).unwrap())
                }
                Err(err_msg) => {
                    let response = Response::new(Body::from(err_msg));
                    Ok(set_response_headers(Response::builder()).body(response.into_body()).unwrap())
                }
            }
        }
        "/uplink" => {
            let params = extract_device_params(req).await;
            match handlers::uplink::handle_uplink(params, &db).await {
                Ok(_) => {
                    let response = Response::new(Body::from("处理 Uplink 消息"));
                    Ok(set_response_headers(Response::builder()).body(response.into_body()).unwrap())
                }
                Err(err_msg) => {
                    let response = Response::new(Body::from(err_msg));
                    Ok(set_response_headers(Response::builder()).body(response.into_body()).unwrap())
                }
            }
        }
        "/downlink" => {
            let params = extract_device_params(req).await;
            match handlers::downlink::handle_downlink(params, &db).await {
                Ok(_) => {
                    let response = Response::new(Body::from("处理 Downlink 消息"));
                    Ok(set_response_headers(Response::builder()).body(response.into_body()).unwrap())
                }
                Err(err_msg) => {
                    let response = Response::new(Body::from(err_msg));
                    Ok(set_response_headers(Response::builder()).body(response.into_body()).unwrap())
                }
            }
        }
        _ => {
            let response = Response::new(Body::from("未找到路径"));
            Ok(set_response_headers(Response::builder()).body(response.into_body()).unwrap())
        }
    }
}

pub async fn run(config: Config) {
    // 初始化数据库时使用 tokio::sync::Mutex
    let db = Arc::new(Mutex::new(Database::new(&config.database_path).expect("无法创建数据库连接")));

    let server_address = config.server_address.parse().unwrap();

    let make_svc = make_service_fn(move |_conn| {
        let db = db.clone();
        async move { Ok::<_, Infallible>(service_fn(move |req| handle_request(req, db.clone()))) }
    });
    let server = Server::bind(&server_address).serve(make_svc);

    println!("服务器启动于 {}", server_address);
    if let Err(e) = server.await {
        eprintln!("服务器错误: {}", e);
    }
}

// 从请求中提取参数
async fn extract_device_params(req: Request<Body>) -> DeviceParams {
    let uri_params = req.uri().query().unwrap_or("");
    let mut dev_eui = "";
    let mut app_eui = "";
    let mut dev_nonce = "";

    for param in uri_params.split('&') {
        let mut parts = param.split('=');
        let key = parts.next().unwrap_or("");
        let value = parts.next().unwrap_or("");

        match key {
            "dev_eui" => dev_eui = value,
            "app_eui" => app_eui = value,
            "dev_nonce" => dev_nonce = value,
            _ => {}
        }
    }

    DeviceParams {
        dev_eui: dev_eui.to_string(),
        app_eui: app_eui.to_string(),
        app_key: "00112233445566778899AABBCCDDEEFF".to_string(),
        dev_nonce: dev_nonce.to_string(),
        dev_addr: "default".to_string(),
        nwk_skey: "default".to_string(),
        app_skey: "default".to_string(),
        join_nonce : "default".to_string(),
    }
    }